package cn.e4j.modular.system.controller;

import cn.afterturn.easypoi.entity.vo.NormalExcelConstants;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.view.PoiBaseView;
import cn.e4j.config.properties.E4jProperties;
import cn.e4j.core.base.controller.BaseController;
import cn.e4j.core.common.annotion.BussinessLog;
import cn.e4j.core.common.annotion.Permission;
import cn.e4j.core.common.constant.Const;
import cn.e4j.core.common.constant.dictmap.UserDict;
import cn.e4j.core.common.exception.BizExceptionEnum;
import cn.e4j.core.dto.Dtos;
import cn.e4j.core.dto.impl.Dto;
import cn.e4j.core.dto.requestDtoResolver.DtoParam;
import cn.e4j.core.dto.requestDtoResolver.DtoWapper;
import cn.e4j.core.reqres.response.ErrorResponseData;
import cn.e4j.core.reqres.response.PageReData;
import cn.e4j.core.reqres.response.ResponseData;
import cn.e4j.core.reqres.response.SuccessResponseData;
import cn.e4j.core.shiro.ShiroKit;
import cn.e4j.core.shiro.ShiroUser;
import cn.e4j.core.util.AppCxt;
import cn.e4j.core.util.InvokeUtil;
import cn.e4j.core.util.LangUtils;
import cn.e4j.core.util.ToolUtil;
import cn.e4j.model.exception.ServiceException;
import cn.e4j.modular.system.entity.SysUser;
import cn.e4j.modular.system.entity.SysUserDevice;
import cn.e4j.modular.system.entity.SysUserRole;
import cn.e4j.modular.system.service.SysUserDeviceService;
import cn.e4j.modular.system.service.SysUserRoleService;
import cn.e4j.modular.system.service.SysUserService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 用户管理
 *
 * @author wenchuan.li
 * @Date 2018/12/08 16:03
 */
@Controller
@RequestMapping("/sys/user")
public class SysUserController extends BaseController {

    @Autowired
    E4jProperties e4jProperties;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysUserDeviceService sysUserDeviceService;

    /**
     * 跳转用户管理页面
     */
    @RequiresPermissions("sys:user:init")
    @RequestMapping(value = {"", "init"})
    public String index() {
        return "/pc/system/user.html";
    }

    /**
     * 跳转到查看管理员列表的页面
     */
    @RequestMapping("/user_add")
    public String addView() {
        return "/pc/system/user_edit.html";
    }

    /**
     * 查询用户列表
     */
    @RequestMapping("/getUserslist")
    @RequiresPermissions("user")
    @ResponseBody
    public ResponseData getUserslist(@DtoParam DtoWapper dtoWapper) {
        Page<Object> page = dtoWapper.getPage();
        Dto inDto = dtoWapper.getDto();

        //inDto.getReqJsonObject();

        inDto.put("IS_DEL", "0");
        //List<Map<String, Object>> result = InvokeUtil.invokeBeanMethod("sysUserServiceImpl,getUserslist", page, inDto);
        List<Map<String, Object>> result = sysUserService.getUserslist(page, inDto);
        return new PageReData(page, result);
    }

    /**
     * 修改用户
     */
    @RequestMapping("/edit")
    @RequiresPermissions("sys:user:init")
    //@BussinessLog(value = "修改用户", key = "account", dict = UserDict.class)
    @ResponseBody
    public ResponseData edit(SysUser user, BindingResult result) {

        // 注意：user 前端只能传需要修改值和主键值，以防把不需要修改的值改成空值
        if (!user.getACCOUNT().equals("admin")) {
            //user.setPASSWORD(null);
            if (user.getPASSWORD().equals("")) {
                user.setPASSWORD(null);
            } else {
                user.setPASSWORD(ShiroKit.md5(user.getPASSWORD()));
            }
            Dto inDto = Dtos.newDto();
            inDto.put("USER_ID", user.getID());
            inDto.put("TYPE", user.getTYPE());
            Dto count = sysUserService.getUserRole(inDto);
            if (count.getBigDecimal("COUNT").compareTo(BigDecimal.ZERO) == 1) {
                sysUserService.deleteUserRole(inDto);
            }
            user.updateById();
        }

//        User oldUser = userService.getById(user.getId());
//        LogObjectHolder.me().set(oldUser);
//        ShiroUser shiroUser = ShiroKit.getUser();
//        this.userService.updateById(UserFactory.editUser(user, oldUser));
        return SUCCESS_TIP;
    }

    /**
     * 获取用户关联的角色
     */
    @RequestMapping("/listUserRoles")
    @RequiresPermissions("sys:user:init")
    @ResponseBody
    public ResponseData listUserRoles(@RequestParam String userId) {
        return new SuccessResponseData(sysUserService.listUserRoles(userId));
    }

    /**
     * 给用户添加角色
     */
    @RequestMapping("/addUserRoles")
    @RequiresPermissions("sys:user:init")
    @ResponseBody
    public ResponseData addUserRoles(@DtoParam DtoWapper dtoWapper) {
        Dto inDto = dtoWapper.getDto();
        List<SysUserRole> list = inDto.getReqList(SysUserRole.class);
        sysUserRoleService.addUserRoles(list);
        return SUCCESS_TIP;
    }

    /**
     * 删除用户角色
     */
    @RequestMapping("/delUserRoles")
    @RequiresPermissions("sys:user:init")
    @ResponseBody
    public ResponseData delUserRoles(@DtoParam DtoWapper dtoWapper) {
        Dto inDto = dtoWapper.getDto();
        List<SysUserRole> list = inDto.getReqList(SysUserRole.class);
        sysUserRoleService.delUserRoles(list);
        return SUCCESS_TIP;
    }

//    /**
//     * 获取销售渠道
//     */
//    @RequestMapping("/listGwaes")
//    @RequiresPermissions("sys:user:init")
//    @ResponseBody
//    public ResponseData listGwaes(@DtoParam DtoWapper dtoWapper) {
//        Dto inDto = dtoWapper.getDto();
//        ShiroUser user = ShiroKit.getUser();
//        inDto.put("lang", LangUtils.getLang(user.getLANG()));
//        return new SuccessResponseData(sysUserService.listGwaes(inDto));
//    }
//
//    /**
//     * 获取用户关联的销售渠道
//     */
//    @RequestMapping("/listUserGwaes")
//    @RequiresPermissions("sys:user:init")
//    @ResponseBody
//    public ResponseData listUserGwaes(@RequestParam String userId) {
//        return new SuccessResponseData(sysUserService.listUserGwaes(userId));
//    }
//
//    /**
//     * 给用户添加销售渠道
//     */
//    @RequestMapping("/addUserGwaes")
//    @RequiresPermissions("sys:user:init")
//    @ResponseBody
//    public ResponseData addUserGwaes(@DtoParam DtoWapper dtoWapper) {
//        Dto inDto = dtoWapper.getDto();
//        List<SysUserDevice> list = inDto.getReqList(SysUserDevice.class);
//        sysUserDeviceService.addUserGwaes(list);
//        return SUCCESS_TIP;
//    }
//
//    /**
//     * 删除用户销售渠道
//     */
//    @RequestMapping("/delUserGwaes")
//    @RequiresPermissions("sys:user:init")
//    @ResponseBody
//    public ResponseData delUserGwaes(@DtoParam DtoWapper dtoWapper) {
//        Dto inDto = dtoWapper.getDto();
//        List<SysUserDevice> list = inDto.getReqList(SysUserDevice.class);
//        sysUserDeviceService.delUserGwaes(list);
//        return SUCCESS_TIP;
//    }

    /**
     * 获取行业一级分类
     */
    @RequestMapping("/listGwbws")
    @RequiresPermissions("sys:user:init")
    @ResponseBody
    public ResponseData listGwbws(@DtoParam DtoWapper dtoWapper) {
        Dto inDto = dtoWapper.getDto();
        ShiroUser user = ShiroKit.getUser();
        inDto.put("GWBWENT", inDto.getString("ENT"));
        inDto.put("lang", LangUtils.getLang(user.getLANG()));
        return new SuccessResponseData(sysUserService.listGwbws(inDto));
    }

    /**
     * 获取用户关联的行业一级分类
     */
    @RequestMapping("/listUserGwbws")
    @RequiresPermissions("sys:user:init")
    @ResponseBody
    public ResponseData listUserGwbws(@RequestParam String userId) {
        return new SuccessResponseData(sysUserService.listUserGwbws(userId));
    }

    /**
     * 给用户添加行业分类
     */
    @RequestMapping("/addUserGwbws")
    @RequiresPermissions("sys:user:init")
    @ResponseBody
    public ResponseData addUserGwbws(@DtoParam DtoWapper dtoWapper) {
        Dto inDto = dtoWapper.getDto();
        List<SysUserDevice> list = inDto.getReqList(SysUserDevice.class);
        sysUserDeviceService.addUserGwbws(list);
        return SUCCESS_TIP;
    }

    /**
     * 删除用户行业分类
     */
    @RequestMapping("/delUserGwbws")
    @RequiresPermissions("sys:user:init")
    @ResponseBody
    public ResponseData delUserGwbws(@DtoParam DtoWapper dtoWapper) {
        Dto inDto = dtoWapper.getDto();
        List<SysUserDevice> list = inDto.getReqList(SysUserDevice.class);
        sysUserDeviceService.delUserGwbws(list);
        return SUCCESS_TIP;
    }

    /**
     * 添加用户
     */
    @RequestMapping("/add")
    @BussinessLog(value = "添加用户", key = "account", dict = UserDict.class)
    @RequiresPermissions("sys:user:init")
    @ResponseBody
    public ResponseData add(SysUser user, BindingResult result) {
        if (result.hasErrors()) {
            return new ErrorResponseData(BizExceptionEnum.REQUEST_NULL.getCode(),
                    BizExceptionEnum.REQUEST_NULL.getMessage());
        }

        // 判断账号是否重复
        SysUser theUser = sysUserService.getByAccount(user.getACCOUNT());
        if (theUser != null) {
            return new ErrorResponseData(BizExceptionEnum.USER_ALREADY_REG.getCode(),
                    BizExceptionEnum.USER_ALREADY_REG.getMessage());
        }

        //验证用户数量
        if(sysUserService.getUserCount() >= e4jProperties.getUserCount()){
            return new ErrorResponseData(BizExceptionEnum.USER_COUNT_HAS_MAX.getCode(),
                    BizExceptionEnum.USER_COUNT_HAS_MAX.getMessage());
        }

        // 完善账号信息
        //user.setSalt(ShiroKit.getRandomSalt(5));
        user.setIS_DEL("0");
        user.setLANG("zh_CN");
        user.setPASSWORD(ShiroKit.md5(user.getPASSWORD()));
        user.setDBC(AppCxt.getParam("ENT"));
        user.insert();
        return SUCCESS_TIP;
    }


    /**
     * 删除用户（逻辑删除）
     */
    @RequestMapping("/delete")
//    @BussinessLog(value = "删除用户", key = "userId", dict = UserDict.class)
    @RequiresPermissions("sys:user:init")
    @ResponseBody
    public ResponseData delete(SysUser user) {
        if (ToolUtil.isEmpty(user.getNAME())) {
            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
        }
        //不能删除超级管理员
        if (user.getID().equals(Const.ADMIN_ID)) {
            throw new ServiceException(BizExceptionEnum.CANT_DELETE_ADMIN);
        }

        sysUserService.delUser(user);
        return SUCCESS_TIP;
    }

    @RequestMapping(value = "/exportsUser", method = RequestMethod.GET)
    @RequiresPermissions("sys:user:init")
    public void exportsUser(ModelMap map, HttpServletRequest request, HttpServletResponse response) {
        Dto inDto = Dtos.newDto();
        inDto.put("is_del", "0");
        List<SysUser> list = sysUserService.getUserslist(inDto);
        ExportParams params = new ExportParams(null, "用户数据", ExcelType.XSSF);
        //params.setFreezeCol(2);
        map.put(NormalExcelConstants.FILE_NAME, "用户数据");
        map.put(NormalExcelConstants.DATA_LIST, list);
        map.put(NormalExcelConstants.CLASS, SysUser.class);
        map.put(NormalExcelConstants.PARAMS, params);
        PoiBaseView.render(map, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);
    }

    @RequestMapping(value = "/importsUser", method = RequestMethod.POST)
    @RequiresPermissions("sys:user:init")
    public void importsUser(MultipartFile file, ModelMap map) {
        Dto inDto = Dtos.newDto();
        ImportParams params = new ImportParams();
        params.setTitleRows(0);//表格标题行数,默认0
        params.setHeadRows(1);//表头行数,默认1
        params.setStartRows(0);//字段真正值和列标题之间的距离 默认0
        try {
            List<SysUser> list = ExcelImportUtil.importExcel(file.getInputStream(), SysUser.class, params);
            System.out.print(list.size());
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(BizExceptionEnum.SERVER_ERROR);
        }
    }

    /**
     * 重置管理员的密码
     */
    @RequestMapping("/reset")
    @BussinessLog(value = "重置管理员密码", key = "userId", dict = UserDict.class)
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public ResponseData reset(@RequestParam Integer userId) {
//        if (ToolUtil.isEmpty(userId)) {
//            throw new ServiceException(BizExceptionEnum.REQUEST_NULL);
//        }
//        User user = this.userService.getById(userId);
//        user.setSalt(ShiroKit.getRandomSalt(5));
//        user.setPassword(ShiroKit.md5(Const.DEFAULT_PWD, user.getSalt()));
//        this.userService.updateById(user);
        return SUCCESS_TIP;
    }

    @ResponseBody
    @RequestMapping(value = "getUser")
    @RequiresPermissions("user")
    public ResponseData getUser() {
        //Dto outDto = Dtos.newDto();
        ShiroUser user = ShiroKit.getUser();
        Dto dto = sysUserService.getUser(user.getID());
        //outDto.put("data", dto);
        return new SuccessResponseData(dto);
    }

    @ResponseBody
    @RequestMapping(value = "getUserCount")
    @RequiresPermissions("user")
    public ResponseData getUserCount() {
        Dto dto = Dtos.newDto();
        dto.put("registerCount", e4jProperties.getUserCount());
        dto.put("userCount", sysUserService.getUserCount());
        return new SuccessResponseData(dto);
    }
}
